package com.main.tripplanner.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.main.tripplanner.persistent.PersistentEntity;
import com.main.tripplanner.persistent.Ticket;


public abstract class BaseServlet extends HttpServlet{

	abstract protected void initialize(/*WebApplicationContext context*/);

	abstract protected void get(HttpServletRequest request, 
			HttpServletResponse response, Ticket ticket) throws IOException;

	abstract protected void post(HttpServletRequest request, 
			HttpServletResponse response, Ticket ticket) throws IOException;

	abstract protected void delete(HttpServletRequest request, 
			HttpServletResponse response, Ticket ticket) throws IOException;

	abstract protected void put(HttpServletRequest request, 
			HttpServletResponse response, Ticket ticket) throws IOException;

	@Override
	public void init() throws ServletException {
		initialize();
	}


	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
		try {
			get(request, response, new Ticket());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		response.addHeader("Access-Control-Allow-Origin", "*");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Ticket ticket = new Ticket();
		ticket.setRequest(getBody(req));
		post(req, resp, ticket);
	}

	protected <T> T getService(Class<T> serviceClass) {
		try {
			WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
			if (context != null)
				return context.getBean(serviceClass);
		} catch (Exception e) {
			//			BaseService.getLogger().error(this.getClass().getSimpleName(), e);
		}
		return null;
	} 

	protected String getParameter(HttpServletRequest request, String name) {
		String value = null;
		if (name != null && !name.isEmpty()) {
			value = request.getHeader(name);
			if (value == null || value.isEmpty()) {
				value = request.getParameter(name);
			}
		}
		return value;
	}

	protected <T> T deserialize(String serialized, Class<T> serializedClass) 
			throws JsonParseException, JsonMappingException, IOException {
		// return Distributable.deserialize(destination, false, serializedClass, logger);
		return PersistentEntity.fromJson(serialized, serializedClass);
	}

	protected void putBody(HttpServletResponse response, Ticket ticket, String contentType) {

		response.setContentType(contentType);
		//		if (ticket.getErrorCode() != null) {
		//			response.addHeader(CommonConstants.ERROR_CODE, ticket.getErrorCode().toString());
		//		}
		//		if (ticket.getErrorMessage() != null) {
		//			response.addHeader(CommonConstants.ERROR_MESSAGE, ticket.getErrorMessage());
		//		}
		if (ticket.getResponse() != null) try {
			PrintWriter out = response.getWriter();
			try {
				out.print(ticket.getResponse());
			} catch (Exception e) {
				e.printStackTrace();
			}
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String getBody(HttpServletRequest request) throws IOException {

		String body = null;
		StringBuilder stringBuilder = new StringBuilder();
		BufferedReader bufferedReader = null;

		try {
			InputStream inputStream = request.getInputStream();
			if (inputStream != null) {
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
				char[] charBuffer = new char[256];
				int bytesRead = -1;
				while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
					stringBuilder.append(charBuffer, 0, bytesRead);
				}
			} else {
				stringBuilder.append("");
			}
		} catch (IOException ex) {
			throw ex;
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException ex) {
					throw ex;
				}
			}
		}

		body = stringBuilder.toString();
		return body;
	}
}
